home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / tls / tls074c.sunsparc.Z / tls074c.sunsparc / lib / vtcl / vtcl.tlib < prev    next >
Encoding:
Text File  |  1995-07-20  |  30.7 KB  |  1,143 lines

  1. #@package: VisualTclX-menu VxMenu VxMenuGetButton VxOptionMenu \
  2.     VxOptionMenuGetSelected VxOptionMenuReplaceOptions VxOptionMenuSetSelected
  3. #
  4. # Menu creation routines
  5. #
  6. #
  7. # VxMenu 
  8. #        builds the insides of a menu bar, Uset VxMenuGetButton to get
  9. #         the reference to a menu item widget, ie VxMenuGetButton $dlog "New"
  10. #
  11. # Syntax:
  12. #           VxMenu formDialog menuBar menuList defaultCB
  13. #
  14. # Arguments:
  15. #       formDialog      - widgetName of form dialog
  16. #    menuBar     - widgetName of menubar
  17. #    menuList    - menu list to build from
  18. #    defaultCB    - default callback to call if they aren't set 
  19. #              in menuList
  20. #
  21. #
  22. #     each item in menulist can contain the following indices
  23. #        OFFSET        Description
  24. #        -----        -----------
  25. #          0        Type, one of following pd, hp, cs, bt, sp,
  26. #                   sp, tb, sc
  27. #          1        Name, name of the button
  28. #          2        mnemonic
  29. #          3        accelerator
  30. #          4        acceleratorString
  31. #          5        callback to associate with button
  32. #          6        If a toggle button this sets the initial state
  33. #
  34. # Use VxMenuGetButton to get the buttons in the menu.
  35. #
  36. proc VxMenu {dlog menubar menuList defaultCB} {
  37.     # different codes for various objects, the only one that is non
  38.     # obvious here is cs, it stands for cascade.
  39.     keylset typeKey pd VtPulldown     hp VtPulldown     cs VtPulldown \
  40.               bt VtPushButton    sp VtSeparator    tb VtToggleButton \
  41.             sc EndCascade
  42.  
  43.     set cascadeStack ""
  44.     foreach m  $menuList {
  45.  
  46.     set type [lindex $m 0]
  47.     set cmd [keylget typeKey $type]
  48.     set label [lindex $m 1]
  49.     
  50.     # convert the ellipses to '+'
  51.     set name [translit ". " "+_" $label]
  52.  
  53.     switch $type {
  54.         pd - hp {
  55.         # Creating a pulldown menu
  56.         lappend cmd "$menubar.$name"
  57.         }
  58.         sc {
  59.         # closing a cascade, pop the last pulldown off the stac
  60.         set lastPd [lvarpop cascadeStack]
  61.         continue
  62.         }
  63.         sp {
  64.         lappend cmd "$lastPd.$name" -allowDuplicateName
  65.         eval $cmd
  66.         continue
  67.         }
  68.         default {
  69.         lappend cmd "$lastPd.$name"
  70.         }
  71.     }
  72.  
  73.     # This is a help pulldown
  74.     if {$type == "hp"} { lappend cmd -help }
  75.  
  76.     # set the label
  77.     lappend cmd -label $label
  78.        
  79.  
  80.     # now set the various placement dependant options
  81.     if { [lindex $m 2] != ""} {
  82.         lappend cmd -mnemonic [lindex $m 2 ]
  83.     }
  84.  
  85.     if { [lindex $m 3] != ""}  {
  86.         lappend cmd  -accelerator [lindex $m 3]
  87.     }
  88.  
  89.     if { [lindex $m 4] != ""} {
  90.         lappend cmd -acceleratorString [lindex $m 4]
  91.     }
  92.  
  93.     set cb [lindex $m 5]
  94.     if {$cb != ""} {
  95.         lappend cmd -callback $cb
  96.     } elseif {$type != "pd" && $type != "hp" && $type != "cs"} {
  97.         lappend cmd -callback $defaultCB
  98.     }
  99.  
  100.     # Toggle buttons have a 6th option, the initial set state
  101.     if { $type == "tb" && [lindex $m 6] != "" } {
  102.         lappend cmd -value [lindex $m 6]
  103.     }
  104.  
  105.     
  106.     switch $type {
  107.         pd - hp {
  108.         set lastPd [eval $cmd]
  109.         VxSetVar $dlog MenuButton($label) $lastPd
  110.         }
  111.         cs {
  112.         set cascade [eval $cmd]
  113.         lvarpush cascadeStack $lastPd
  114.         set lastPd $cascade
  115.          VxSetVar $dlog MenuButton($label) $lastPd
  116.         }
  117.         default {
  118.         set but [eval $cmd]
  119.  
  120.         VxSetVar $dlog MenuButton($label) $but
  121.         }
  122.     }
  123.     }
  124. }
  125.  
  126. #
  127. #VxMenuGetButton
  128. #    Gets the widget name of a button in a menu created with VxMenu
  129. #
  130. #Syntax:
  131. #    VxMenuGetButton widgetName buttonLabel
  132. #
  133. #Arguments:
  134. #    widgetName    - Widget name of the menu created by VxMenu
  135. #    buttonLabel     - label of the button to retrieve
  136. #
  137. proc VxMenuGetButton {dlog name} {
  138.     return [VxGetVar $dlog MenuButton($name)]
  139. }
  140.  
  141.  
  142. #------------------------------------------------------------
  143. #
  144. # Routines for option menus
  145. #
  146. #
  147. # VxOptionMenu object.name label options defaultCB selection
  148. #
  149. #       Returns an option menu that contains pushbuttons for the
  150. #       options specified.
  151. #
  152. #    object.name     - widget hierarchy of option menu
  153. #       label           - option menu label, 
  154. #                 (e.g. "filename:")
  155. #       options         - tcl list of options 
  156. #              (to be used as labels for the pushbuttons) 
  157. #                  (e.g. {one two three})
  158. #       defaultCB       - callback called when option menu changes
  159. #       selection       - option which is initially selected
  160. #                         (e.g. "one")
  161. #
  162. #
  163. # VxOptionMenuGetSelected menu 
  164. #
  165. #       Returns the label of the selected item in an option menu that
  166. #       was created by VxOptionMenu
  167. #
  168. #       widgetName       - name of menu returned by VxOptionMenu
  169. #
  170. # VxOptionMenuSetSelected menu selection
  171. #
  172. #       Sets the option menu's value to be <selection>. "selection" refers
  173. #       to the label of the selected pushbutton.  The option menu 
  174. #       referenced must have been created by VxOptionMenu.
  175. #
  176. #       widgetName       - name of menu returned by VxOptionMenu
  177. #       selection        - label of option to be selected.
  178. #
  179. #
  180. # VxOptionMenuReplaceOptions widgetName options selection
  181. #
  182. #           Returns the label of the selected item in an option menu that
  183. #
  184. #       widgetName      - name of menu returned by VxOptionMenu
  185. #       options         - tcl list of options 
  186. #              (to be used as labels for the pushbuttons) 
  187. #                  (e.g. {one two three})
  188. #       selection       - option which is initially selected
  189. #                         (e.g. "one")
  190. #
  191. #
  192.  
  193. proc _SetOptions {menu options selection} {
  194.     #
  195.     # make option menu buttons and assign to userdata
  196.     set i 0
  197.     foreach buttonLabel $options {
  198.         set button [VtPushButton $menu.button$i -label $buttonLabel]
  199.         keylset allButtons button$i $buttonLabel
  200.         incr i
  201.     }
  202.     if {![info exists allButtons]} {
  203.         VtSetValues $menu -userData {}
  204.         return $menu
  205.     } else {
  206.         keylset allButtons ":labelList" $options
  207.         VtSetValues $menu -userData $allButtons
  208.     }
  209.  
  210.  
  211.     if {$selection == "" } {
  212.         #set to the first one
  213.         VtSetValues $menu -selectedWidget $menu.button0
  214.     } else {
  215.         VxOptionMenuSetSelected $menu $selection
  216.     }
  217. }
  218.  
  219.  
  220. proc VxOptionMenu {name label options CB selection} {
  221.     set menu [VtOptionMenu $name -label $label]
  222.     if {$CB != ""} {
  223.         VtSetValues $menu -callback $CB
  224.     }
  225.  
  226.     _SetOptions $menu $options $selection 
  227.     return $menu
  228. }
  229.  
  230. proc VxOptionMenuGetSelected {menu} {
  231.     set selectedWidget [VtGetValues $menu -selectedWidget]
  232.     set allButtons [VtGetValues $menu -userData]
  233.     set button [VxGetShortName $selectedWidget]
  234.     return [keylget allButtons $button]
  235. }
  236.  
  237. proc VxOptionMenuSetSelected {menu selected} {
  238.     set allButtons [VtGetValues $menu -userData]
  239.     set labelList [keylget allButtons ":labelList"]
  240.     set button [lsearch $labelList $selected]
  241.     if {$button == -1} {
  242.         error "VxOptionMenuSetSelected: selection invalid: $selected"
  243.     }
  244.  
  245.     VtSetValues $menu -selectedWidget $menu.button$button
  246. }
  247.  
  248. proc VxOptionMenuReplaceOptions {menu options selection} {
  249.         #
  250.     # get button list
  251.     set allButtons [VtGetValues $menu -userData]
  252.  
  253.     #
  254.     # destroy old buttons
  255.     if {$allButtons != "{}"} {
  256.             foreach button [keylkeys allButtons] {
  257.              if {$button != ":labelList"} {
  258.                  VtDestroy $menu.$button
  259.              }
  260.         }
  261.     }
  262.  
  263.     #
  264.     # make new buttons
  265.     _SetOptions $menu $options $selection
  266. }
  267.  
  268. #@packend
  269.  
  270.  
  271. #@package: VisualTclX-label VxList VxText VxRowColumn VxRadioBox \
  272.     VxCheckBox VxComboBox      
  273.  
  274. #
  275. # The following five routines add the -label -title functionality to 
  276. # VtList VtText VtRowColumn VtRadioBox VtCheckBox
  277. #
  278.  
  279. proc VxList {name args} {
  280.     eval _VxBox VtList $name $args
  281. }
  282.  
  283. proc VxText {name args} {
  284.     eval _VxBox VtText $name $args
  285. }
  286.  
  287. proc VxRadioBox {name args} {
  288.     eval _VxBox VtRadioBox $name $args
  289. }
  290.  
  291. proc VxCheckBox {name args} {
  292.     eval _VxBox VtCheckBox $name $args
  293. }
  294.  
  295. proc VxRowColumn {name args} {
  296.     eval _VxBox VtRowColumn $name $args
  297. }
  298.  
  299. proc VxComboBox {name args} {
  300.     eval _VxBox VtComboBox $name $args
  301. }
  302.  
  303. proc _VxBox {cmd name args} {
  304.     set parts [split $name .]
  305.     set wName [lindex $parts end]
  306.  
  307.     # delete name 
  308.     set parts [lreplace $parts end end]  
  309.     set parent [join $parts .]
  310.  
  311.     # list of options that we are going to override, if any
  312.     # of the geometry options are set, we need to set them on the
  313.     # invisible form.
  314.     set geoOptions {}
  315.     foreach opt {
  316.       leftOffset leftSide  alignLeft
  317.       rightOffset rightSide alignRight
  318.       topOffset topSide alignTop
  319.       bottomOffset bottomSide alignBottom
  320.       below above
  321.     } {
  322.       lappend geoOptions -$opt -MOTIF_$opt -CHARM_$opt
  323.     }
  324.   
  325.     # These two options are the ones that we are really interested in
  326.  
  327.     # These two options are the ones that we are really interested in
  328.     # if either one of these two exist we create a form wrapper around
  329.     # the object.
  330.     set allOptions [concat $geoOptions "-title -label"]
  331.     
  332.     foreach opt $allOptions {
  333.     set found($opt) ""
  334.     }
  335.  
  336.     set lastFound ""
  337.     set newArgs ""
  338.     foreach arg $args {
  339.  
  340.     if {$lastFound != ""} {
  341.         set found($lastFound) $arg
  342.         set lastFound ""
  343.         continue
  344.     }
  345.  
  346.     set lastFound [lmatch -exact $allOptions $arg]
  347.     if {$lastFound != ""} {
  348.         continue
  349.     }
  350.  
  351.     lappend newArgs $arg
  352.     }
  353.  
  354.     # Create the args list for the outer form
  355.     set boxArgs ""
  356.     foreach opt $geoOptions {
  357.     if {$found($opt) != ""} {
  358.         lappend boxArgs $opt $found($opt)
  359.     }
  360.     }
  361.  
  362.     set form $parent
  363.     if {$found(-title) != "" || $found(-label) != ""} {
  364.     # make the form
  365.     set boxname  [format "%s_box" $wName]
  366.  
  367.     set form     [eval VtForm $parent.$boxname $boxArgs\
  368.                            -marginHeight 0 -marginWidth 0]
  369.  
  370.     if {$found(-title) != ""} {
  371.         set label    [VtLabel $form.label -label $found(-title) \
  372.                  -topSide FORM]
  373.           set target   [eval $cmd $form.$wName $newArgs -topSide $label \
  374.                -leftSide FORM -rightSide FORM -bottomSide FORM]
  375.     } else {
  376.         set label    [VtLabel $form.label -label $found(-label) \
  377.                           -topSide FORM -bottomSide FORM]
  378.           set target   [eval $cmd $form.$wName $newArgs \
  379.                      -leftSide $label -leftOffset 5 \
  380.                     -rightSide FORM \
  381.                      -topSide FORM -bottomSide FORM]
  382.     }
  383.  
  384.         VxSetVar $target "form" $form
  385.         VxSetVar $target "label" $label
  386.  
  387.     } else {
  388.     set target [eval $cmd $form.$wName $newArgs $boxArgs]
  389.     }
  390.  
  391.     return $target
  392. }
  393.  
  394.  
  395. #@packend
  396.  
  397. #@package:  VisualTclX-align VxAlignBaseLines VxCenterVertically \
  398.     VxSetLeftOffsets VxAlignedForm
  399.  
  400. #================================================================== API ===
  401. # VxAlignBaseLines
  402. #
  403. #       Given two widgets which have been created with the sourceWidget
  404. #    -alignTop to the targetWidget, sets the top offset of the sourceWidget
  405. #    so that its baseline lines up with the targetWidget's baseline.
  406. #
  407. # Parameters:
  408. #    targetWidget  - the widget you are aligning to
  409. #    sourceWidget  - the widget that will be adjusted
  410. #    currentOffset - any topOffset the targetWidget already has which must
  411. #            be taken into account (OPTIONAL, default=0)
  412. # Globals:
  413. # Returns:
  414. #--------------------------------------------------------------------------
  415. proc VxAlignBaseLines {targetWidget sourceWidget {currentOffset 0}} {
  416.     set source [VtGetValues $sourceWidget -baseLineList]
  417.     set target [VtGetValues $targetWidget -baseLineList]
  418.     set diff [expr {($target - $source) + $currentOffset}]
  419.     VtSetValues $sourceWidget -MOTIF_topOffset $diff
  420. }
  421.  
  422. #================================================================== API ===
  423. # VxCenterVertically
  424. #
  425. #       Given two widgets which have been created with the sourceWidget
  426. #    -alignTop to the targetWidget, sets the top offset of the sourceWidget
  427. #    so that the targetWidget is in the center.
  428. #
  429. # Parameters:
  430. #    targetWidget - the widget you are centering around
  431. #    sourceWidget - the widget that will be adjusted
  432. # Globals:
  433. # Returns:
  434. #--------------------------------------------------------------------------
  435. proc VxCenterVertically {targetWidget sourceWidget} {
  436.     set source [VtGetValues $sourceWidget -height]
  437.     set target [VtGetValues $targetWidget -height]
  438.     set diff [expr {($target - $source) / 2}]
  439.  
  440.     VtSetValues $sourceWidget -MOTIF_topOffset $diff
  441. }
  442.  
  443.  
  444. #================================================================== API ===
  445. # VxSetLeftOffsets
  446. #
  447. #       Given a list of widgets which have been created with -alignRight
  448. #    to the previous label, sets the left offset of the first
  449. #    widget so that all the labels fit on the form
  450. #
  451. # Parameters:
  452. #    widgets     - a list of widgets, the first widget in the list is
  453. #              the one that gets modified
  454. #    MOTIFOffset - any MOTIF leftOffset the first widget already has which
  455. #              must be taken into account (OPTIONAL, default=0)
  456. #    CHARMOffset - any CHARM leftOffset the first widget already has which
  457. #              must be taken into account (OPTIONAL, default=0)
  458. # Globals:
  459. # Returns:
  460. #--------------------------------------------------------------------------
  461. proc VxSetLeftOffsets {widgets {MOTIFOffset 0} {CHARMOffset 0}} {
  462.  
  463.     set max 0
  464.     set CHARM_max 0
  465.     set firstWidget [lindex $widgets 0]
  466.  
  467.     # find the widest widget
  468.     for {set i 0} {$i < [llength $widgets]} {incr i} {
  469.         set width [VtGetValues [lindex $widgets $i] -width]
  470.         if {$width > $max} then {
  471.             set max $width
  472.         }
  473.         set CHARM_width [string length [VtGetValues \
  474.             [lindex $widgets $i] -label]]
  475.         if {$CHARM_width > $CHARM_max} then {
  476.             set CHARM_max $CHARM_width
  477.         }
  478.     }
  479.  
  480.     # set the left offset of the first widget
  481.     set diff [expr {$max - [VtGetValues $firstWidget -width] \
  482.         + 1 + $MOTIFOffset}]
  483.  
  484.     VtSetValues $firstWidget -MOTIF_leftOffset $diff
  485.  
  486.     set CHARM_diff [expr {$CHARM_max - [string length [VtGetValues \
  487.                         $firstWidget -label]] \
  488.         + 1 + $CHARMOffset}]
  489.  
  490.     VtSetValues $firstWidget -CHARM_leftOffset $CHARM_diff
  491. }
  492.  
  493.  
  494.  
  495. # ----------------------------------------
  496. # VxAlignedForm
  497. #
  498. #    Description:
  499. #       Creates one or more vertically aligned widgets,
  500. #       with right-justified labels.
  501. #       Each Label and Widget are in their own form.
  502. #       Their widget names may be retrieved as follows:
  503. #
  504. #       (in the list below, $name is the name returned by the
  505. #        VxAlignedForm call, and $n is the position of the widget.
  506. #        "1" is the first widget)
  507. #
  508. #       Form:        VxGetVar $name "form$n"
  509. #       Widget:        VxGetVar $name "widget$n"
  510. #       Label:        VxGetVar $name "label$n"
  511. #
  512. #    Usage:
  513. #       VxAlignedForm widgetName dataList
  514. #
  515. #    Arguments:
  516. #       widgetName      - Name of parent.thisWidget
  517. #       dataList        - A list of lists, each containing a label and
  518. #                         another list containing the desired widget call 
  519. #                         and any desired arguments
  520. #
  521. #    Example:
  522. #       set form [VxAlignedForm $parent.Texts\
  523. #                   { {"The 1st label"  {VtText -columns 30 -value "stuff 1"}}
  524. #                     {"The second label"  {VtText -value "stuff 2"}}
  525. #                     {"3rd label"  {VtText -value "stuff 3"}}
  526. #                     {"Combo"  VtComboBox} } ]
  527. # --------------------
  528. #
  529. proc VxAlignedForm { args } {
  530.     set argc [llength $args]
  531.     if {$argc != 2} {
  532.         error "VxAlignedForm: wrong number of args: $argc"
  533.     }
  534.  
  535.     set wname [lvarpop args]
  536.     set dataList [lvarpop args]
  537.  
  538.     set form [VtForm $wname -marginWidth 0 -marginHeight 0]
  539.  
  540.     set index 0
  541.     set maxWidth 0
  542.     foreach list $dataList {
  543.         # First element is the label
  544.         set labelstr [lindex $list 0]
  545.         # Second element is the widget call and list-o-arguments
  546.         set wlist [lindex $list 1]
  547.         set widgetCall [lvarpop wlist]
  548.  
  549.         incr index
  550.         set tform\
  551.             [VtForm $form.Tform$index\
  552.                 -marginWidth 0\
  553.                 -marginHeight 0\
  554.                 -leftSide FORM\
  555.                 -rightSide FORM]
  556.  
  557.         set label\
  558.             [VtLabel $tform.Label$index\
  559.                 -label $labelstr\
  560.                 -labelRight\
  561.                 -leftSide FORM\
  562.                 -rightSide NONE\
  563.                 -topSide FORM\
  564.                 -bottomSide FORM\
  565.                 -alignLeft NONE]
  566.         set widget [eval $widgetCall $tform.Text$index $wlist]
  567.         VtSetValues $widget\
  568.             -alignLeft NONE\
  569.             -leftSide $label\
  570.             -topSide FORM\
  571.             -bottomSide FORM\
  572.             -rightSide FORM
  573.         set width [VtGetValues $label -width]
  574.         if {$width > $maxWidth} {
  575.             set maxWidth $width
  576.         }
  577.         VxSetVar $form "widget$index" $widget
  578.         VxSetVar $form "label$index" $label
  579.         VxSetVar $form "form$index" $tform
  580.     }
  581.  
  582.     set maxWidth [expr {$maxWidth + 1}]
  583.     for {set i 1} {$i <= $index} {incr i} {
  584.         set label [VxGetVar $form "label$i"]
  585.         set tform [VxGetVar $form "form$i"]
  586.         set width [VtGetValues $label -width]
  587.         if {$width < $maxWidth} {
  588.             set offset [expr {$maxWidth - $width}]
  589.             VtSetValues $tform -leftOffset $offset
  590.         }
  591.     }
  592.  
  593.     return $form
  594. }
  595.  
  596. # ----------------------------------------
  597.  
  598. #@packend
  599.  
  600.  
  601.  
  602. #@package:  VisualTclX-misc VxEndFormCB VxGetShortName
  603.  
  604. #================================================================== API ===
  605. # VxGetShortName
  606. #
  607. #       Given a widget name, strips off all the parent widgets, leaving
  608. #    the short widget name
  609. #
  610. # Parameters:
  611. #    widget - the widget name to strip
  612. # Globals:
  613. # Returns:
  614. #    the stripped widget name
  615. #--------------------------------------------------------------------------
  616. proc VxGetShortName {widget} {
  617.     set wl [split $widget .]
  618.     set wi [expr "[llength $wl] - 1"]
  619.     set short [lindex $wl $wi]
  620.     return $short
  621. }
  622.  
  623. proc VxEndFormCB {cbs} {
  624.     VtDestroyDialog [keylget cbs dialog]
  625. }
  626.  
  627. #@packend
  628.  
  629. #@package: VisualTclX-var VxSetVar VxGetVar VxWidgetVarRef
  630.  
  631. #
  632. # _VxWidgetVarError
  633. #
  634. #   Convert error in error stack to something that makes sense for the
  635. # variable.  This is needed becaused error stacks containing upvared variables
  636. # don't contain the real name.
  637. proc _VxWidgetVarError {msg realVar} {
  638.     global errorInfo errorCode
  639.     regsub {"var"} $msg \"$realVar\" msg
  640.     regsub {"var"} $errorInfo \"$realVar\" errorInfo
  641.     error $msg $errorInfo $errorCode
  642. }
  643.  
  644. #
  645. # VxSetVar
  646. #
  647. #  Set the value of a per-widget variable frame variable.
  648. #
  649. # Parameters:
  650. #   o widgetName (I) - Name of widget that the variable is associated with.
  651. #   o varName (I) - Name of the variable.  May be a scalar or array reference.
  652. #   o value (I) - The value is assigned to the variable
  653. # Returns:
  654. #   Value is returned.
  655. #
  656. proc VxSetVar {widgetName varName value} {
  657.     upvar #0 "VTVars:$widgetName:$varName" var
  658.     
  659.     set stat [catch {
  660.         set result [set var $value]
  661.     } msg]
  662.  
  663.     if {$stat == 1} {
  664.         _VxWidgetVarError $msg $varName
  665.     }
  666.     return $result
  667. }
  668.  
  669. #
  670. # VxGetVar
  671. #
  672. #  Get the value of a per-widget variable frame variable.
  673. #
  674. # Parameters:
  675. #   o widgetName (I) - Name of widget that the variable is associated with.
  676. #   o varName (I) - Name of the variable.  May be a scalar or array reference.
  677. # Returns:
  678. #   Value is returned.
  679. #
  680. proc VxGetVar {widgetName varName} {
  681.     upvar #0 "VTVars:$widgetName:$varName" var
  682.  
  683.     set stat [catch {
  684.         set result [set var]
  685.     } msg]
  686.  
  687.     if {$stat == 1} {
  688.         _VxWidgetVarError $msg $varName
  689.     }
  690.     return $result
  691. }
  692.  
  693. #
  694. # VxWidgetVarRef
  695. #
  696. #   Return a "reference" for per-widget variable frames variable.  This allows
  697. # the variable to be passed by reference to other Tcl commands. eg:
  698. #
  699. #    array names [VxWidgetVarRef my.widget.path data]
  700. #
  701. # Parameters:
  702. #   o widgetName (I) - Name of widget that the variable is associated with.
  703. #   o varName (I) - Name of the variable.  May be a scalar or array, but not
  704. #     an element of the arrray.
  705. # Returns:
  706. #   A reference to the variable usable in the current scope.
  707. #
  708. proc VxWidgetVarRef {widgetName varName} {
  709.     set ref "VTVars:$widgetName:$varName"
  710.     uplevel global $ref
  711.     return $ref
  712. }
  713.  
  714.  
  715. #@package: VisualTclX-SpinButton VxSpinButton VxSpinButtonSetMinValue \
  716.     VxSpinButtonSetMaxValue 
  717.  
  718. #================================================================== INT ===
  719. #  SB:CheckBoundsCB
  720. #       Checks the text field value is within the upper and lower bounds.
  721. # Parameters:
  722. #    instance  - the widget name of the enclosing form of the SpinButton
  723. #    underCB   - a callback for when the value goes below the lower
  724. #            bound.  If set to null, wraps the value around.
  725. #    overCB    - a callback for when the value goes over the upper
  726. #            bound.  If set to null, wraps the value around.
  727. # Globals:
  728. #    SBlower     - array of lower value boundary values, indexed by
  729. #              instance
  730. #    SBupper     - array of upper value boundary values, indexed by
  731. #              instance
  732. # Returns:
  733. #--------------------------------------------------------------------------
  734. proc SB:CheckBoundsCB {instance underCB overCB cbs} {
  735.  
  736.     global SBlower SBupper 
  737.  
  738.     set field [VxGetVar $instance text]
  739.     set newValue [VtGetValues $field -value] 
  740.  
  741.     if {![ctype digit $newValue]} then {
  742.            VtSetValues $field -value $SBlower($instance)
  743.         return
  744.     }
  745.  
  746.         if {$newValue > $SBupper($instance)} then {
  747.         if {[string length $overCB]==0} then {
  748.                VtSetValues $field -value $SBupper($instance)
  749.             return
  750.         } else {
  751.             $overCB $cbs
  752.             return
  753.         }
  754.     }
  755.     
  756.         if {$newValue < $SBlower($instance)} then {
  757.         if {[string length $underCB]==0} then {
  758.                VtSetValues $field -value $SBlower($instance)
  759.             return
  760.         } else {
  761.             $underCB $cbs
  762.             return
  763.         }
  764.         }
  765.  
  766. } ;# SB:CheckBoundsCB
  767.  
  768.  
  769. #================================================================== INT ===
  770. #  SB:ChangeValueCB
  771. #       Increases or decreases the SpinButton value, wrapping the value
  772. #    around upper and lower bounds.
  773. # Parameters:
  774. #    instance  - the widget name of the enclosing form of the SpinButton
  775. #    underCB   - a callback for when the value goes below the lower
  776. #            bound.  If set to null, wraps the value around.
  777. #    overCB    - a callback for when the value goes over the upper
  778. #            bound.  If set to null, wraps the value around.
  779. #    increment - how much to increase/decrease the value by
  780. #    direction - up: increase the value, down: decrease the value
  781. #    upOp      - operation to perform on increment when the "up" button
  782. #            is pressed 
  783. #    dnOp      - operation to perform on increment when the "down" button
  784. #            is pressed 
  785. # Globals:
  786. #    SBlower     - array of lower value boundary values, indexed by
  787. #              instance
  788. #    SBupper     - array of upper value boundary values, indexed by
  789. #              instance
  790. # Returns:
  791. #--------------------------------------------------------------------------
  792. proc SB:ChangeValueCB {instance underCB overCB increment \
  793.                direction upOp dnOp cbs} {
  794.  
  795.     global SBlower SBupper 
  796.  
  797.     set field [VxGetVar $instance text]
  798.  
  799.     set currentValue [VtGetValues $field -value]
  800.     if {[string length $currentValue] == 0} then {
  801.         set currentValue $SBlower($instance)
  802.         }
  803.         if {[ctype digit $currentValue] == 0} then {
  804.         set currentValue $SBlower($instance)
  805.         }
  806.  
  807.         if {$direction == "up"} {
  808.             set newValue [expr "$currentValue $upOp $increment"]
  809.         } else {
  810.             set newValue [expr "$currentValue $dnOp $increment"]
  811.         }
  812.     
  813.         if {$newValue>$SBupper($instance)} then {
  814.         if {[string length $overCB]==0} then {
  815.                 if {$direction == "up"} {
  816.                 set newValue $SBlower($instance)
  817.             } else {
  818.                 set newValue $SBupper($instance)
  819.             }
  820.         } else {
  821.             $overCB $cbs
  822.             return
  823.         }
  824.     }
  825.     
  826.         if {$newValue<$SBlower($instance)} then {
  827.         if {[string length $underCB]==0} then {
  828.                 if {$direction == "up"} {
  829.                 set newValue $SBlower($instance)
  830.             } else {
  831.                 set newValue $SBupper($instance)
  832.             }
  833.         } else {
  834.             $underCB $cbs
  835.             return
  836.         }
  837.         }
  838.  
  839.        VtSetValues $field -value $newValue
  840.  
  841. } ;# SB:ChangeValueCB
  842.  
  843.  
  844. #================================================================== EXT ===
  845. # VxSpinButtonSetMinValue
  846. #       Sets the lower boundary for a spin button
  847. # Parameters:
  848. #    instance  - the instance name of the SpinButton
  849. #    lower     - the lower value boundary
  850. # Globals:
  851. #    SBlower     - array of lower value boundary values, indexed by
  852. #              instance
  853. # Returns:
  854. #--------------------------------------------------------------------------
  855. proc VxSpinButtonSetMinValue {instance lower} {
  856.     global SBlower 
  857.  
  858.     set SBlower($instance) $lower
  859.  
  860.     set textW [VxGetVar $instance text]
  861.  
  862.     set currentValue [VtGetValues $textW -value]
  863.     if {[string length $currentValue] == 0} then {
  864.         set currentValue $SBlower($instance)
  865.         }
  866.         if {[ctype digit $currentValue] == 0} then {
  867.         set currentValue $SBlower($instance)
  868.         }
  869.  
  870.     if {$currentValue < $SBlower($instance)} then {
  871.         set currentValue $SBlower($instance)
  872.     }
  873.  
  874.     VtSetValues $textW -value $currentValue
  875.  
  876. } ;# VxSpinButtonSetMinValue
  877.  
  878.  
  879. #================================================================== EXT ===
  880. # VxSpinButtonSetMaxValue
  881. #       Sets the upper boundary for a spin button
  882. # Parameters:
  883. #    instance  - the instance name of the SpinButton
  884. #    upper     - the upper value boundary
  885. # Globals:
  886. #    SBupper     - array of upper value boundary values, indexed by
  887. #              instance
  888. # Returns:
  889. #--------------------------------------------------------------------------
  890. proc VxSpinButtonSetMaxValue {instance upper} {
  891.     global SBupper 
  892.  
  893.     set SBupper($instance) $upper
  894.  
  895.     set textW [VxGetVar $instance text]
  896.  
  897.     set currentValue [VtGetValues $textW -value]
  898.     if {[string length $currentValue] == 0} then {
  899.         set currentValue $SBlower($instance)
  900.         }
  901.         if {[ctype digit $currentValue] == 0} then {
  902.         set currentValue $SBlower($instance)
  903.         }
  904.  
  905.     if {$currentValue > $SBupper($instance)} then {
  906.         set currentValue $SBupper($instance)
  907.     }
  908.  
  909.     VtSetValues $textW -value $currentValue
  910.  
  911. } ;# VxSpinButtonSetMaxValue
  912.  
  913.  
  914. #================================================================== EXT ===
  915. # getPixmapDirectory
  916. #       Returns the location of the Visual Tcl pixmap directory.
  917. # Parameters:
  918. #       NONE
  919. #
  920. proc getPixmapDirectory {} {
  921.     global env
  922.     if {[info exists env(VTCL_HOME)]} {
  923.         set pixmapDir "$env(VTCL_HOME)/pixmaps"
  924.     } else {
  925.         if {[info exists env(WSHOMEDIR)]} {
  926.             set pixmapDir "$env(WSHOMEDIR)/pixmaps"
  927.             } else {
  928.             set pixmapDir "/lib/vtcl/pixmaps"
  929.         }
  930.     }
  931.     return $pixmapDir
  932. }
  933.  
  934.  
  935. #================================================================== EXT ===
  936. # VxSpinButton
  937. #       Creates a SpinButton, which consists of a text field and two
  938. #    buttons which increase and decrease the numeric value in the text
  939. #    field within upper and lower bounds.
  940. # Parameters:
  941. #    widget    - the widget name of this SpinButton
  942. #    width     - the width of the Text widget
  943. #    lower     - the lower boundary value 
  944. #    underCB   - a callback for when the value goes below the lower
  945. #            bound.  If set to "", the package automatically wraps the
  946. #            value around to the upper value.
  947. #    upper     - the upper boundary value
  948. #    overCB    - a callback for when the value goes over the upper
  949. #            bound.  If set to "", the package automatically wraps the
  950. #            value around to the lower value.
  951. #    increment - how much to increase/decrease the value by
  952. #    default   - the inital default value
  953. #    userCB    - a callback which checks the value of the Text widget, or ""
  954. #            for no callback
  955. #    position  - standard geometryArgs for the Text widget.
  956. #    upOp (OPT)- operation to perform on increment when the "up" button
  957. #            is pressed (+ if not present)
  958. #    dnOp (OPT)- operation to perform on increment when the "down" button
  959. #            is pressed (- if not present)
  960. # Globals:
  961. #    SBlower     - array of lower boundary values, indexed by widget
  962. #    SBupper     - array of upper boundary values, indexed by widget
  963. # Returns:
  964. #    The name of the enclosing form widget
  965. # Notes:
  966. #    Attached to the form widget returned, is the name of the text widget
  967. #    and rowcol widget containing the buttons:
  968. #
  969. #    VxGetVar $sb text     for the text widget
  970. #    VxGetVar $sb rowcol   for the rowcol widget
  971. #--------------------------------------------------------------------------
  972. proc VxSpinButton {widget width lower underCB upper overCB \
  973.                increment default userCB position \
  974.                {upOp "+"} {dnOp "-"}} {
  975.  
  976.     global SBlower SBupper
  977.  
  978.         
  979.     #set iconPath /usr/lib/X11/sco/ScoAdmin/common
  980.         set iconPath [getPixmapDirectory]
  981.  
  982.     set SB [eval VtForm $widget -marginHeight 0 -marginWidth 0 $position]
  983.  
  984.     if {$userCB != ""} then {
  985.         set text [VtText $SB.text -rows 1 -columns $width \
  986.             -value $default -callback $userCB \
  987.             -leftSide FORM -topSide FORM -bottomSide FORM \
  988.             -MOTIF_topOffset 2 -MOTIF_bottomOffset 4 ]
  989.     } else {
  990.         set text [VtText $SB.text -rows 1 -columns $width \
  991.             -value $default \
  992.             -callback "SB:CheckBoundsCB $SB \"$underCB\" \"$overCB\""\
  993.             -leftSide FORM -topSide FORM -bottomSide FORM \
  994.             -MOTIF_topOffset 2 -MOTIF_bottomOffset 4 ]
  995.     }
  996.  
  997.     set SBlower($SB) $lower
  998.     set SBupper($SB) $upper
  999.  
  1000.     if {! [VtInfo -charm]} then {
  1001.         set rowcol [VtRowColumn $SB.rc -packing TIGHT -spacing 0 \
  1002.         -leftOffset 0 -leftSide NONE -topSide FORM -rightSide FORM \
  1003.         -bottomSide FORM -xmArgs {XmNmarginHeight 0 XmNmarginWidth 0}]
  1004.  
  1005.         VtSetValues $text -rightSide $rowcol \
  1006.                   -rightOffset 0
  1007.  
  1008.         set upBut [VtPushButton $rowcol.up \
  1009.             -pixmap $iconPath/up_ptr.xbm \
  1010.             -callback "SB:ChangeValueCB $SB {$underCB} \
  1011.                   {$overCB} $increment up $upOp $dnOp" \
  1012.                 -label "^"]
  1013.  
  1014.         set downBut [VtPushButton $rowcol.down \
  1015.             -pixmap $iconPath/down_ptr.xbm \
  1016.             -callback "SB:ChangeValueCB $SB {$underCB} \
  1017.                   {$overCB} $increment down $dnOp $dnOp" \
  1018.                 -label "v"]
  1019.  
  1020.         VxSetVar $SB rowcol  $rowcol
  1021.         VxSetVar $SB upBut   $upBut
  1022.         VxSetVar $SB downBut $downBut
  1023.     } else {
  1024.         VtSetValues $text -rightSide FORM
  1025.     }
  1026.  
  1027.     VxSetVar $SB text    $text
  1028.  
  1029.     return $SB
  1030.  
  1031. } ;# VxSpinButton
  1032.  
  1033. #@packend
  1034.  
  1035.  
  1036.  
  1037. #@package: VisualTclX-backwardsCompat WxMenu WxMenuGetButton WxOptionMenu \
  1038.     WxOptionMenuGetSelected WxOptionMenuReplaceOptions WxOptionMenuSetSelected \
  1039.     WxList WxText WxRowColumn WxRadioBox WxCheckBox WxComboBox \
  1040.     WxAlignBaseLines WxCenterVertically WxSetLeftOffsets WxAlignedForm \
  1041.     WxEndFormCB WxGetShortName WxSetVar WxGetVar WxWidgetVarRef WxSpinButton \
  1042.     WxSpinButtonSetMinValue WxSpinButtonSetMaxValue 
  1043.  
  1044. proc WxMenu {dlog menubar menuList defaultCB} {
  1045.     return [VxMenu $dlog $menubar $menuList $defaultCB]
  1046. }
  1047.  
  1048. proc WxMenuGetButton {dlog name} {
  1049.     return [VxMenuGetButton $dlog $name]
  1050. }
  1051.  
  1052. proc WxOptionMenu {name label options CB selection} {
  1053.     return [VxOptionMenu $name $label $options $CB $selection]
  1054. }
  1055.  
  1056. proc WxOptionMenuGetSelected {menu} {
  1057.     return [VxOptionMenuGetSelected $menu]
  1058. }
  1059.  
  1060. proc WxOptionMenuSetSelected {menu selected} {
  1061.     return [VxOptionMenuSetSelected $menu $selected]
  1062. }
  1063.  
  1064. proc WxOptionMenuReplaceOptions {menu options selection} {
  1065.     return [VxOptionMenuReplaceOptions $menu $options $selection]
  1066. }
  1067.  
  1068. proc WxList {name args} {
  1069.     return [eval "VxList \"$name\" $args"]
  1070. }
  1071.  
  1072. proc WxText {name args} {
  1073.     return [eval "VxText \"$name\" $args"]
  1074. }
  1075.  
  1076. proc WxRadioBox {name args} {
  1077.     return [eval "VxRadioBox \"$name\" $args"]
  1078. }
  1079.  
  1080. proc WxCheckBox {name args} {
  1081.     return [eval "VxCheckBox \"$name\" $args"]
  1082. }
  1083.  
  1084. proc WxRowColumn {name args} {
  1085.     return [eval "VxRowColumn \"$name\" $args"]
  1086. }
  1087.  
  1088. proc WxComboBox {name args} {
  1089.     return [eval "VxComboBox \"$name\" $args"]
  1090. }
  1091.  
  1092. proc WxAlignBaseLines {targetWidget sourceWidget {currentOffset 0}} {
  1093.     return [VxAlignBaseLines $targetWidget $sourceWidget $currentOffset]
  1094. }
  1095.  
  1096. proc WxCenterVertically {targetWidget sourceWidget} {
  1097.     return [VxCenterVertically $targetWidget $sourceWidget]
  1098. }
  1099.  
  1100. proc WxSetLeftOffsets {widgets {MOTIFOffset 0} {CHARMOffset 0}} {
  1101.     return [VxSetLeftOffsets $widgets $MOTIFOffset $CHARMOffset]
  1102. }
  1103.  
  1104. proc WxAlignedForm {args} {
  1105.     return [eval "VxAlignedForm $args"]
  1106. }
  1107.  
  1108. proc WxGetShortName {widget} {
  1109.     return [VxGetShortName $widget]
  1110. }
  1111.  
  1112. proc WxEndFormCB {cbs} {
  1113.     return [VxEndFormCB $cbs]
  1114. }
  1115.  
  1116. proc WxSetVar {widgetName varName value} {
  1117.     return [VxSetVar $widgetName $varName $value]
  1118. }
  1119.  
  1120. proc WxGetVar {widgetName varName} {
  1121.     return [VxGetVar $widgetName $varName]
  1122. }
  1123.  
  1124. proc WxWidgetVarRef {widgetName varName} {
  1125.     return [VxWidgetVarRef $widgetName $varName]
  1126. }
  1127.  
  1128. proc WxSpinButtonSetMinValue {instance lower} {
  1129.     return [VxSpinButtonSetMinValue $instance $lower]
  1130. }
  1131.  
  1132. proc WxSpinButtonSetMaxValue {instance upper} {
  1133.     return [VxSpinButtonSetMaxValue $instance $upper]
  1134. }
  1135.  
  1136. proc WxSpinButton {widget width lower underCB upper overCB \
  1137.                increment default userCB position \
  1138.                {upOp "+"} {dnOp "-"}} {
  1139.     return [VxSpinButton $widget $width $lower $underCB $upper $overCB \
  1140.             $increment $default $userCB $position $upOp $dnOp]
  1141. }
  1142.